package drds.plus.sql_process.abstract_syntax_tree.expression.order_by;

import drds.plus.common.jdbc.Parameters;
import drds.plus.sql_process.abstract_syntax_tree.IExecutePlanVisitor;
import drds.plus.sql_process.abstract_syntax_tree.ObjectCreateFactory;
import drds.plus.sql_process.abstract_syntax_tree.expression.item.Item;
import drds.plus.sql_process.type.Type;

public class OrderByImpl implements OrderBy {

    private Item item;
    /**
     * true : asc, false: desc
     */
    private Boolean asc = true;

    public void setColumn(Item item) {
        this.item = item;

    }

    public void setAsc(Boolean asc) {
        this.asc = asc;

    }

    public Item getItem() {
        return item;
    }

    public Boolean getAsc() {
        return asc;
    }

    public OrderBy assignment(Parameters parameters) {
        OrderBy orderBy = ObjectCreateFactory.createOrderBy();
        orderBy.setAsc(this.getAsc());
        if (this.getItem() instanceof Item) {
            orderBy.setColumn(this.getItem().assignment(parameters));
        } else {
            orderBy.setColumn(this.getItem());
        }

        return orderBy;
    }

    public void accept(IExecutePlanVisitor executePlanVisitor) {
        executePlanVisitor.visit(this);
    }

    public String getAlias() {
        return this.item.getAlias();
    }

    public void setTableName(String alias) {
        this.item.setTableName(alias);

    }

    public void setColumnName(String alias) {
        this.item.setColumnName(alias);

    }

    public String getTableName() {
        return this.item.getTableName();
    }

    public String getColumnName() {
        return this.item.getColumnName();
    }

    public Type getDataType() {
        return this.item.getType();
    }

    public OrderBy copy() {
        OrderBy orderBy = ObjectCreateFactory.createOrderBy();
        orderBy.setColumn(this.getItem().copy());
        orderBy.setAsc(this.getAsc());
        return orderBy;
    }

    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append("OrderByImpl [");
        if (item != null) {
            sb.append("item=");
            sb.append(item);
            sb.append(", ");
        }
        sb.append("asc=");
        sb.append(asc);
        sb.append("]");
        return sb.toString();
    }

    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }

        final OrderByImpl other = (OrderByImpl) obj;
        if (this.item != other.item && (this.item == null || !this.item.equals(other.item))) {
            return false;
        }
        return this.asc == other.asc;
    }

    public String toStringWithInden(int inden) {
        StringBuilder sb = new StringBuilder();
        sb.append(item);
        if (!asc) {
            sb.append(" desc");
        }
        return sb.toString();
    }

    public int hashCode() {
        int hash = 5;
        hash = 37 * hash + (this.item != null ? this.item.hashCode() : 0);
        hash = 37 * hash + (this.asc ? 1 : 0);
        return hash;
    }
}
